package video;

import java.io.File;
import java.util.*;

/**
 * A class that creates and manager a play list.
 * 
 * @version 0.3 December 01, 2009.
 * @author Heitor Meira de Melo.
 */
public class PlayList {
	private List<File> playList;
	private int currentVideoPosition;
	private final int ZERO_POSITION = 0;

	/**
	 * Constructor of a Play List.
	 */
	public PlayList() {
		playList = new ArrayList<File>();
		currentVideoPosition = 0;
	}

	/**
	 * Constructor of a Play List that receive a List of video path's, to the
	 * play list.
	 * 
	 * @param files
	 *            The List of video files.
	 * @throws Exception
	 *             If the list if null or empty.
	 */
	public PlayList(List<String> files) throws Exception {
		playList = new ArrayList<File>();
		currentVideoPosition = 0;
		addPlayList(files);
	}

	/**
	 * Gets the path where the newVideo have been extracted.
	 * 
	 * @return A String with the path
	 */
	private String getPath() {
		String path;
		try {
			path = Class.class.getResource("/bailey.flv").toString();
			path = path.replaceFirst("jar:file:", "");
			path = path.replaceFirst(".jar!", "");
		} catch (Exception ex) {
			path = "Videos/Samples/bailey.flv";
		}
		return path;
	}

	/**
	 * Add a list of video path's to the current Play List.
	 * 
	 * @param files
	 *            A list of video path's.
	 * @return A list Files.
	 */
	public List<File> addPlayList(List<String> files) {
		File newsVideo = new File(getPath());

		Iterator<String> itPaths = files.iterator();

		while (itPaths.hasNext()) {
			File file = new File(itPaths.next());
			if (file.exists()) {
				playList.add(file);
				continue;
			}
			if (file.getName().equals("news")) {
				playList.add(newsVideo);
			}
		}

		if (playList.isEmpty()) {
			playList.add(newsVideo);
		}
		positionToZero();
		return playList;
	}

	/**
	 * Set the current play list position to Zero.
	 */
	public void positionToZero() {
		currentVideoPosition = ZERO_POSITION;
	}

	/**
	 * Replaces the current list with a new list.
	 * 
	 * @param files
	 *            The new list.
	 * @return The new list.
	 * @throws Exception
	 *             If the argument is null or empty.
	 */
	public List<File> setPlayList(List<String> files) throws Exception {
		clearPlayList();
		addPlayList(files);
		positionToZero();
		return playList;
	}

	/**
	 * Clear the current play list.
	 */
	public void clearPlayList() {
		playList = new ArrayList<File>();
	}

	/**
	 * Add a video to the play list
	 * 
	 * @param newFile
	 *            A path of video to add.
	 * @return The File.
	 */
	public File addVideo(File newFile) throws Exception {
		if (!newFile.exists() || newFile == null) {
			throw new Exception("Invalid File.");
		}

		playList.add(newFile);

		return newFile;
	}

	/**
	 * Get the current play list.
	 * 
	 * @return The current play list.
	 */
	public List<File> getPlayList() {
		return playList;
	}

	/**
	 * Remove a file from the play list.
	 * 
	 * @param file
	 *            the file to remove.
	 */
	public void remove(File file) {
		playList.remove(file);
	}

	/**
	 * Remove all the files in the play list.
	 */
	public void removeAll() {
		clearPlayList();
	}

	/**
	 * Provides the next video in play list.
	 * 
	 * @return The video.
	 */
	public File next() {
		currentVideoPosition++;
		if (currentVideoPosition >= playList.size()) {
			positionToZero();
		}
		return playList.get(currentVideoPosition);
	}

	/**
	 * Return the current position in the play list.
	 * 
	 * @return The current position.
	 */
	public int curretPosition() {
		return currentVideoPosition;
	}

	/**
	 * set the current position to one position ago.
	 * 
	 * @return The File of the video in the preview position.
	 */
	public File preview() {
		currentVideoPosition--;
		if (currentVideoPosition < ZERO_POSITION) {
			currentVideoPosition = getMaxPosition();
		}
		return playList.get(currentVideoPosition);
	}

	/**
	 * Return the current video.
	 * 
	 * @return The current video.
	 */
	public File currentVideo() {
		return playList.get(currentVideoPosition);
	}

	/**
	 * Set the position in the play list to a new position.
	 * 
	 * @param newPosition
	 *            The new position.
	 * @throws Exception
	 *             If the position is out of bounds, (minor than 0 or more than
	 *             play list size).
	 */
	public void toPosition(int newPosition) throws Exception {
		if (newPosition < ZERO_POSITION || newPosition > playList.size()) {
			throw new Exception("Invalid Position.");
		}
		currentVideoPosition = newPosition;
	}

	/**
	 * Return the Max position of the current play list.
	 * 
	 * @return The max position.
	 */
	private int getMaxPosition() {
		return playList.size() - 1;
	}
}